#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "config.h"

int get_cmd_type(char *cmd)
{
	if(!strcmp("ls",cmd))   return LS;
	if(!strcmp("quit",cmd))   return QUIT;
	if(!strcmp("pwd",cmd))   return PWD;
	if(strstr(cmd,"cd")!=NULL)   return CD;
	if(strstr(cmd,"get")!=NULL)   return GET;
	if(strstr(cmd,"put")!=NULL)   return PUT;
	
	return 100;
}

char *getDesDir(char *cmsg)
{
	char *p;
	p = strtok(cmsg," ");
	p = strtok(NULL," ");
	return p;
}

void msg_handler(struct Msg msg,int fd)
{
	char dataBuf[1024] = {0};
	char *file = NULL;
	int fdfile;
	
	printf("cmd:%s\n",msg.data);
	int ret = get_cmd_type(msg.data);

	switch(ret){
	case LS:
	case PWD:
		msg.type = 0;
		FILE *r = popen(msg.data,"r");
		fread(msg.data,sizeof(msg.data),1,r);
		write(fd,&msg,sizeof(msg));
		break;
	case CD:
		msg.type =1;
		char *dir = getDesDir(msg.data);
		printf("dir:%s\n",dir);
		chdir(dir);
		break;
	case GET:
		file = getDesDir(msg.data);
		
		if(access(file,F_OK) == -1)
		{
			strcpy(msg.data,"No this file!");
			write(fd,&msg,sizeof(msg));
		}else{
			msg.type = DOFILE;
			fdfile = open(file,O_RDWR);
			read(fdfile,dataBuf,sizeof(dataBuf));
			close(fdfile);
			strcpy(msg.data,dataBuf);
			write(fd,&msg,sizeof(msg));
		}
		break;
	case PUT:
		fdfile = open(getDesDir(msg.data),O_RDWR|O_CREAT,0760);
		write(fdfile,msg.secondBuf,strlen(msg.secondBuf));
		close(fdfile);
		break;
	case QUIT:
		printf("client quit!\n");
		exit(-1);
	}
}

int main(int argc,char **argv)
{
	struct sockaddr_in s_addr;
	struct sockaddr_in c_addr;
	int sock_fd;
	int n_read;
	int c_fd;
	int len;
	struct Msg msg;
	
	//if param error
	if(argc != 3)
	{
		printf("param is error!\n");
		exit(-1);
	}
 
	memset(&s_addr,0,sizeof(struct sockaddr_in));
	memset(&c_addr,0,sizeof(struct sockaddr_in));
	
	//1.socket
	 sock_fd = socket(AF_INET,SOCK_STREAM,0); 
	if(sock_fd == -1)
	{
		perror("Socket");
		exit(-1);
	} 	
	//2.bind
	s_addr.sin_family = AF_INET;
	s_addr.sin_port = htons(atoi(argv[2])); //zi jie xu wen ti
	inet_aton(argv[1],&s_addr.sin_addr);
	bind(sock_fd,(struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));

	//3.listen
	 listen(sock_fd,7);
	//4.accept
	len = sizeof(struct sockaddr_in);
	while(1){
	c_fd = accept(sock_fd, (struct sockaddr *)&c_addr,&len);
	if(c_fd == -1)
	{
		perror("accept");
		exit(-1);
	}

		printf("connection success!\n");
		printf("Client ip:%s\n",inet_ntoa(c_addr.sin_addr));
	if(fork() == 0)
	{
	while(1){
	//5.read
	memset(msg.data,0,sizeof(msg.data));
	n_read = read(c_fd,&msg,sizeof(msg));	 
	if(n_read == -1)
	{
		perror("read");
	}else if(n_read == 0)
	{
		printf("client out\n");
		break;
	}
	else if(n_read >0){
		msg_handler(msg,c_fd);		
      }
	}
	}
	}
	close(c_fd);
	close(sock_fd);
	return 0;
}
